package com.lx.camera2;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.Face;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.media.ExifInterface;
import android.media.Image;
import android.media.ImageReader;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.media.MediaScannerConnection;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.provider.MediaStore;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Size;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.lx.camera2.service.MyService;
import com.lx.camera2.ui.AwbFragment;
import com.lx.camera2.ui.CircleImageView;
import com.lx.camera2.ui.ShutterButton;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

@SuppressLint("newApi")
public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getName();
    private CameraManager cameraManager;
    private LocationManager locationManager;
    private CameraCharacteristics cameraCharacteristics;
    private CameraDevice cameraDevice;
    private CameraCaptureSession previewSession;
    private CameraCaptureSession recorderSession;
    private MediaRecorder mediaRecorder;
    private ImageReader imageReader;
    private CaptureRequest.Builder previewRequestBuilder;
    private CaptureRequest.Builder recorderRequestBuilder;
    private CaptureRequest.Builder takePhotoRequestBuilder;
    private StreamConfigurationMap map;
    private Handler childHandler,mainHandler;
    private SurfaceHolder holder;
    private MediaPlayer player;
    private ShutterButton shutterButton;
    private Button snapShot;
    private CircleImageView display;
    private TextView takePhoto,video,photo_delay,slowMotion,awb;
    private TextView second_3,second_5;
    private TextView timer;
    private TextView faces;
    private AwbFragment awbFragment;
    private FragmentManager fragmentManager;
    private Chronometer chronometer;
    private LinearLayout second;
    private ImageView change;
    private ImageView awb1,awb2,awb3;
    private File videoFile;
    private String[] cameraIdList;
    private int cameraId = CameraCharacteristics.LENS_FACING_FRONT;
    private int time = 3;
    private int[] faceDetectModes;
    private CountDownTimer  count = new CountDownTimer(time * 1000, 1000) {
        @SuppressLint("SetTextI18n")
        @Override
        public void onTick(long millisUntilFinished) {
            timer.setText(millisUntilFinished / 1000 + "");
            flag++;
        }
        @Override
        public void onFinish() {
            Toast.makeText(MainActivity.this, "done!", Toast.LENGTH_SHORT).show();
            try {
                takePhoto();
                timer.setVisibility(View.GONE);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }
    };
    private int flag = 0;
    private boolean openCameraFlag;
    private boolean slowMotionFlag;
    private int currentAwbMode = CaptureRequest.CONTROL_AWB_MODE_AUTO;
    private static final int REQUEST_PERMISSION = 1;
    public static final int REMOVE_SNAPSHOT_IMAGEVIEW = 1;
    private WindowManager windowManager;
    private MyService.MyBinder myBinder;
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myBinder = (MyService.MyBinder) service;
            Log.e(TAG, "onServiceConnected: "+myBinder );
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.what == REMOVE_SNAPSHOT_IMAGEVIEW){
                Log.e(TAG, "handleMessage: 执行了" );
                windowManager.removeView(myBinder.floatView);
            }
        }
    };


    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent("heying.service");
        intent.setPackage(getPackageName());
        bindService(intent, connection, Context.BIND_AUTO_CREATE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getSupportActionBar().hide();
        SharedPreferences preferences = getPreferences(MODE_PRIVATE);
        time = Integer.parseInt(preferences.getString("time","3"));
        createCountDownTimer(time);
        Log.e(TAG, "onCreate:  time = "+time );
        requestPermissions(new String[]{Manifest.permission.CAMERA,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.RECORD_AUDIO,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.SYSTEM_ALERT_WINDOW},REQUEST_PERMISSION);
        initView();

        Log.e(TAG, "onCreate: "+getLocation() );
        takePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!awbFragment.isHidden()){
                    fragmentManager.beginTransaction().hide(awbFragment).commit();
                }
                shutterButton.setMode(ShutterButton.PHOTO_MODE);
                buttonColorChange();
                second.setVisibility(View.GONE);
                snapShot.setVisibility(View.INVISIBLE);
                chronometer.setVisibility(View.INVISIBLE);
                startPreViewSession();
            }
        });
        video.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!awbFragment.isHidden()){
                    fragmentManager.beginTransaction().hide(awbFragment).commit();
                }
                if (shutterButton.currentMode.equals(ShutterButton.VIDEO_RECORDING_MODE)){
                    video.setEnabled(false);
                }else {
                    faces.setVisibility(View.INVISIBLE);
                    video.setEnabled(true);
                    snapShot.setVisibility(View.INVISIBLE);
                    shutterButton.setMode(ShutterButton.VIDEO_MODE);
                    buttonColorChange();
                    second.setVisibility(View.GONE);
                }
            }
        });
        photo_delay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!awbFragment.isHidden()){
                    fragmentManager.beginTransaction().hide(awbFragment).commit();
                }
                shutterButton.setMode(ShutterButton.PHOTO_DELAY_MODE);
                buttonColorChange();
                second.setVisibility(View.VISIBLE);
                snapShot.setVisibility(View.INVISIBLE);
                Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.anim_alpha);
                second.startAnimation(animation);
                chronometer.setVisibility(View.INVISIBLE);
                startPreViewSession();
            }
        });
        slowMotion.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!awbFragment.isHidden()){
                    fragmentManager.beginTransaction().hide(awbFragment).commit();
                }
                slowMotion.setTextColor(Color.GREEN);
                takePhoto.setTextColor(Color.WHITE);
                video.setTextColor(Color.WHITE);
                photo_delay.setTextColor(Color.WHITE);
                awb.setTextColor(Color.WHITE);
                second.setVisibility(View.GONE);
                snapShot.setVisibility(View.INVISIBLE);
                chronometer.setVisibility(View.INVISIBLE);
                slowMotionFlag = !slowMotionFlag;
                shutterButton.setMode(ShutterButton.PHOTO_MODE);
                startPreViewSession();
                Toast.makeText(MainActivity.this, "慢动作开启状态："+slowMotionFlag, Toast.LENGTH_SHORT).show();
            }
        });
        awb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (awbFragment.isHidden()){
                    awb.setTextColor(Color.GREEN);
                    slowMotion.setTextColor(Color.WHITE);
                    takePhoto.setTextColor(Color.WHITE);
                    video.setTextColor(Color.WHITE);
                    photo_delay.setTextColor(Color.WHITE);
                    second.setVisibility(View.GONE);
                    snapShot.setVisibility(View.INVISIBLE);
                    chronometer.setVisibility(View.INVISIBLE);
                    fragmentManager.beginTransaction().show(awbFragment).commit();
                    shutterButton.setMode(ShutterButton.PHOTO_MODE);
                    startPreViewSession();
                }
            }
        });
        awb1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                currentAwbMode = CaptureRequest.CONTROL_AWB_MODE_TWILIGHT;
                startPreView();
            }
        });
        awb2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                currentAwbMode = CaptureRequest.CONTROL_AWB_MODE_AUTO;
                startPreView();
            }
        });
        awb3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                currentAwbMode = CaptureRequest.CONTROL_AWB_MODE_SHADE;
                startPreView();
            }
        });
        snapShot.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    if (Build.VERSION.SDK_INT >= 23) {
                        if (!Settings.canDrawOverlays(getApplicationContext())) {
                            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));//应用的包名，可直接跳转到这个应用的悬浮窗设置；
                            startActivity(intent);
                        } else {
                                myBinder.openWindow();
                        }
                    } else {
                        myBinder.openWindow();
                    }
                    myBinder.openWindow();
                    takePhotoRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
                    // 根据设备方向计算设置照片的方向
                    int result;
                    if (cameraId == CameraCharacteristics.LENS_FACING_FRONT) {
                        result = 90;
                    } else {  // back-facing
                        result = 270;
                    }
                    takePhotoRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, result);
                    takePhotoRequestBuilder.addTarget(imageReader.getSurface());
                    recorderSession.capture(takePhotoRequestBuilder.build(), new CameraCaptureSession.CaptureCallback() {
                        @Override
                        public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                            super.onCaptureCompleted(session, request, result);
                            removeSnapShotImage();
                        }
                    }, null);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
        });
        shutterButton.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if (ShutterButton.PHOTO_MODE.equals(shutterButton.currentMode)) {
                    Log.e(TAG, "onLongClick: " + "长按按钮的操作被执行了");
                    try {
                        shotToShot();
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }
                return true;//true表示过滤掉单击事件
            }
        });
        second_3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MainActivity.this.time = Integer.parseInt(second_3.getText().toString());
                timer.setVisibility(View.INVISIBLE);
                timer.setText(String.valueOf(MainActivity.this.time));
                createCountDownTimer(MainActivity.this.time);
            }
        });
        second_5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MainActivity.this.time = Integer.parseInt(second_5.getText().toString());
                timer.setVisibility(View.INVISIBLE);
                timer.setText(String.valueOf(MainActivity.this.time));
                createCountDownTimer(MainActivity.this.time);
            }
        });
        shutterButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (shutterButton.currentMode) {
                    case ShutterButton.PHOTO_MODE:
                        try {
                            takePhoto();
                        } catch (CameraAccessException e) {
                            e.printStackTrace();
                        }
                        break;
                    case ShutterButton.PHOTO_DELAY_MODE:
                        Log.e(TAG, "onClick: time = "+time);
                        if (flag == 0){
                            timer.setVisibility(View.VISIBLE);
                            count.start();
                        }else {
                            timer.setVisibility(View.INVISIBLE);
                            count.cancel();
                            try {
                                takePhoto();
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                            flag = 0;
                        }
                        break;
                    case ShutterButton.VIDEO_MODE:
                        if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
                        &&checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                            snapShot.setVisibility(View.VISIBLE);
                            chronometer.setVisibility(View.VISIBLE);
                            chronometer.setBase(SystemClock.elapsedRealtime());
                            chronometer.start();
                            shutterButton.setMode(ShutterButton.VIDEO_RECORDING_MODE);
                            player.start();
                            startVideo();
                        }else {
                            Toast.makeText(MainActivity.this, "请在设置中开启录音和存储权限", Toast.LENGTH_LONG).show();
                        }
                        break;
                    case ShutterButton.VIDEO_RECORDING_MODE:
                        snapShot.setVisibility(View.INVISIBLE);
                        chronometer.stop();
                        shutterButton.setMode(ShutterButton.VIDEO_MODE);
                        player.start();
                        stopVideo();
                        galleryAddVideo(MainActivity.this);
//                        MediaMetadataRetriever media = new MediaMetadataRetriever();
//                        media.setDataSource(videoFile.getAbsolutePath());
//                        Bitmap bitmap = media.getFrameAtTime(1, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
                        //获取视频第一帧作为图片展示
                        Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(videoFile.getPath(), MediaStore.Video.Thumbnails.MINI_KIND);
                        display.setImageBitmap(bitmap);
                        openCamera();
                        break;
                }
            }
        });
        change.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    if (cameraDevice!=null){
                        cameraDevice.close();
                        cameraDevice = null;
                    }
                    if (previewSession!=null){
                        previewSession.close();
                        previewSession = null;
                    }
                    if (imageReader!=null){
                     imageReader.close();
                     imageReader = null;
                    }
                    changeFacing();
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
        });
        display.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent openAlbumIntent = new Intent(Intent.ACTION_VIEW);
                openAlbumIntent.setType("vnd.android.cursor.dir/video");
                startActivity(openAlbumIntent);
            }
        });
    }

    private void removeSnapShotImage() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Message message = handler.obtainMessage();
                    message.what = REMOVE_SNAPSHOT_IMAGEVIEW;
                    TimeUnit.SECONDS.sleep(1);
                    handler.sendMessage(message);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 初始化view
     */
    private void initView(){
        windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        locationManager = getSystemService(LocationManager.class);
        fragmentManager = getSupportFragmentManager();
        awbFragment = (AwbFragment) fragmentManager.findFragmentById(R.id.awbFragment);
        fragmentManager.beginTransaction().hide(awbFragment).commit();
        awb1 = findViewById(R.id.awb1);
        awb2 = findViewById(R.id.awb2);
        awb3 = findViewById(R.id.awb3);
        shutterButton = findViewById(R.id.shutterButton);
        snapShot = findViewById(R.id.snapShot);
        snapShot.setVisibility(View.INVISIBLE);
        SurfaceView surfaceView = findViewById(R.id.surfaceView);
        takePhoto = findViewById(R.id.take_photo);
        faces = findViewById(R.id.faces);
        video = findViewById(R.id.video);
        photo_delay = findViewById(R.id.photo_delay);
        slowMotion = findViewById(R.id.slowMotion);
        awb = findViewById(R.id.awb);
        buttonColorChange();
        chronometer = findViewById(R.id.chronometer);
        chronometer.setVisibility(View.INVISIBLE);
        second = findViewById(R.id.second);
        second_3 = findViewById(R.id.second_3);
        second_5 = findViewById(R.id.second_5);
        timer = findViewById(R.id.timer);
        second.setVisibility(View.GONE);
        display = findViewById(R.id.display);
        change = findViewById(R.id.change);
        player = MediaPlayer.create(MainActivity.this, R.raw.shutter);
        holder = surfaceView.getHolder();
        HandlerThread handlerThread = new HandlerThread("Camera2");
        handlerThread.start();
        mainHandler = new Handler(getMainLooper());
        childHandler = new Handler(handlerThread.getLooper());
        //surfaceview开启监听
        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(@NonNull SurfaceHolder holder) {
                Log.e(TAG, "surfaceCreated: " );
                if (openCameraFlag){
                    openCamera();
                }

            }

            @Override
            public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
                Log.e(TAG, "surfaceChanged: " );
            }

            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
                Log.e(TAG, "surfaceDestroyed: " );
                openCameraFlag = true;
            }
        });
    }

    public void createCountDownTimer(int time){
        count = new CountDownTimer(time * 1000, 1000) {
            @SuppressLint("SetTextI18n")
            @Override
            public void onTick(long millisUntilFinished) {
                timer.setText(millisUntilFinished / 1000 + "");
                flag++;
            }
            @Override
            public void onFinish() {
                Toast.makeText(MainActivity.this, "done!", Toast.LENGTH_SHORT).show();
                try {
                    takePhoto();
                    timer.setVisibility(View.GONE);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
        };
    }
    /**
     * 打开摄像头
     */
    @SuppressLint("MissingPermission")
    public void openCamera() {
        try {
            cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);
            cameraIdList = cameraManager.getCameraIdList();
            cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraIdList[cameraId]);
            map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            //用于判断是否支持人脸识别，以及支持到了那种程度
            faceDetectModes = cameraCharacteristics.get(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);
            //最多能检测的人脸数量
            int maxFaceCount = cameraCharacteristics.get(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT);
            Size optimalSize = getOptimalSize();
            imageReader = ImageReader.newInstance(optimalSize.getWidth(), optimalSize.getHeight(), ImageFormat.JPEG, 1);
            //获取到的图片的监听
            imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
                @Override
                public void onImageAvailable(ImageReader reader) {
                    Image image = reader.acquireNextImage();
                    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                    byte[] data = new byte[buffer.remaining()];
                    buffer.get(data);
                    image.close();
                    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                    display.setImageBitmap(bitmap);
                    try {
                        galleryAddPhoto(MainActivity.this, bitmap);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }, null);
            cameraManager.openCamera(cameraIdList[cameraId], new CameraDevice.StateCallback() {
                @Override
                public void onOpened(@NonNull CameraDevice camera) {
                    cameraDevice  = camera;
                    try {
                        cameraDevice.createCaptureSession(Arrays.asList(holder.getSurface(),imageReader.getSurface()), new CameraCaptureSession.StateCallback() {
                            @Override
                            public void onConfigured(@NonNull CameraCaptureSession session) {
                                previewSession = session;
                                startPreView();//必须放在这个回调方法里
                            }

                            @Override
                            public void onConfigureFailed(@NonNull CameraCaptureSession session) {

                            }
                        }, null);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }

                }

                @Override
                public void onDisconnected(@NonNull CameraDevice camera) {
                    if (cameraDevice!=null){
                        cameraDevice.close();
                        cameraDevice = null;
                    }
                }

                @Override
                public void onError(@NonNull CameraDevice camera, int error) {
                    Toast.makeText(MainActivity.this, "请正确打开相机", Toast.LENGTH_SHORT).show();
                }
            }, mainHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
    /**
     * 切换摄像头
     * @throws CameraAccessException
     */
    private void changeFacing() throws CameraAccessException {
        if (cameraId == CameraCharacteristics.LENS_FACING_FRONT){
            cameraId = CameraCharacteristics.LENS_FACING_BACK;
        }else {
            cameraId = CameraCharacteristics.LENS_FACING_FRONT;
        }
        openCamera();
    }
    /**
     * 授予权限的回调
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSION && hasPermissions()){
            Log.e(TAG, "onRequestPermissionsResult: " );
            openCamera();
        }else {
            Toast.makeText(MainActivity.this, "请在设置中开启预览权限", Toast.LENGTH_SHORT).show();
        }
    }
    /**
     * 功能颜色变化
     */
    private void buttonColorChange(){
        if (shutterButton.currentMode.equals(ShutterButton.PHOTO_MODE)){
            takePhoto.setTextColor(Color.GREEN);
            video.setTextColor(Color.WHITE);
            photo_delay.setTextColor(Color.WHITE);
            slowMotion.setTextColor(Color.WHITE);
            awb.setTextColor(Color.WHITE);
        }else if (shutterButton.currentMode.equals( ShutterButton.VIDEO_MODE)){
            video.setTextColor(Color.GREEN);
            takePhoto.setTextColor(Color.WHITE);
            photo_delay.setTextColor(Color.WHITE);
            slowMotion.setTextColor(Color.WHITE);
            awb.setTextColor(Color.WHITE);
        }else {
            photo_delay.setTextColor(Color.GREEN);
            video.setTextColor(Color.WHITE);
            takePhoto.setTextColor(Color.WHITE);
            slowMotion.setTextColor(Color.WHITE);
            awb.setTextColor(Color.WHITE);
        }
    }

    /**
     * 获取最高人脸检测级别
     * @return
     */
    private int getFaceDetectMode() {
        if (faceDetectModes == null) {
            return CaptureRequest.STATISTICS_FACE_DETECT_MODE_FULL;
        } else {
            return faceDetectModes[faceDetectModes.length - 1];
        }
    }

    private void onCameraImagePreviewed(Context context,CaptureResult result) {
        Face[] faces = result.get(CaptureResult.STATISTICS_FACES);
        MainActivity.this.faces.setText("人脸数量："+faces.length);
        }


        /**
         * 判断是否有权限
         * @return
         */
    private boolean hasPermissions() {
        return checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
        }

    /**
     * 获取最优的拍照图片的size
     * @return
     */
    public Size getOptimalSize(){
        Size[] sizes = map.getOutputSizes(SurfaceTexture.class);
        List<Size> sizeList = Arrays.asList(sizes);
        Collections.sort(sizeList, new Comparator<Size>() {
            @Override
            //o1-o2是升序，o2-o1是降序
            public int compare(Size o1, Size o2) {
                return o1.getWidth()*o1.getHeight() - o2.getWidth()*o2.getHeight();
            }
        });
        return sizeList.get(sizeList.size()-1);
    }
    /**
     * 开启预览
     */
    public void startPreView(){
        try {
            if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                previewRequestBuilder.addTarget(holder.getSurface());
                // 自动对焦
                previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                //触发对焦
//                previewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CaptureRequest.CONTROL_AF_TRIGGER_START);
                //自动白平衡
                previewRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE, currentAwbMode);
//            previewRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_SHADE);
//             previewRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_INCANDESCENT);
                previewRequestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, getFaceDetectMode());
                previewSession.setRepeatingRequest(previewRequestBuilder.build(), new CameraCaptureSession.CaptureCallback() {
                    @Override
                    public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                        super.onCaptureCompleted(session, request, result);
                        onCameraImagePreviewed(MainActivity.this, result);

                    }
                }, null);
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }


    /**
     * 拍照功能
     * @throws CameraAccessException
     */
    public void takePhoto() throws CameraAccessException {
        if (checkSelfPermission(Manifest.permission.CAMERA)==PackageManager.PERMISSION_GRANTED
        &&checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED
        &&checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)==PackageManager.PERMISSION_GRANTED) {
            takePhotoRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            // 开启自动曝光
//            takePhotoRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
            //闪光灯持续打开
            takePhotoRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
            // 根据设备方向计算设置照片的方向
            int result;
            if (cameraId == CameraCharacteristics.LENS_FACING_FRONT) {
                result = 90;
            } else {  // back-facing
                result = 270;
            }
            takePhotoRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, result);

            takePhotoRequestBuilder.addTarget(imageReader.getSurface());
            previewSession.capture(takePhotoRequestBuilder.build(), new CameraCaptureSession.CaptureCallback() {
                @Override
                public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
                    super.onCaptureStarted(session, request, timestamp, frameNumber);
                    player.start();
                }
            }, childHandler);
        }else {
            Toast.makeText(MainActivity.this, "请在设置中开启相机和存储权限", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 拍照模式下，长按button开启连拍功能
     * @throws CameraAccessException
     */
    public void shotToShot() throws CameraAccessException {
        CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
        builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
        builder.set(CaptureRequest.FLASH_MODE,CaptureRequest.FLASH_MODE_TORCH);
        // 根据设备方向计算设置照片的方向
        int result;
        if (cameraId == CameraCharacteristics.LENS_FACING_FRONT) {
            result = 90;
        } else {  // back-facing
            result = 270;
        }
        builder.set(CaptureRequest.JPEG_ORIENTATION, result);
        builder.addTarget(imageReader.getSurface());
        CaptureRequest request = builder.build();
        List<CaptureRequest> requestList = new ArrayList<>();
        int i = 0;
        while (i < 5){
            requestList.add(request);
            i++;
        }
        previewSession.captureBurst(requestList,null,null);
    }
    /**
     * 开启录像
     */
    public void startVideo(){
            prepareRecorder();
            try {
                recorderRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
                recorderRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO);
                recorderRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE,currentAwbMode);
                recorderRequestBuilder.addTarget(holder.getSurface());
                Surface recorderSurface = mediaRecorder.getSurface();
                recorderRequestBuilder.addTarget(recorderSurface);
                imageReader = ImageReader.newInstance(1920, 1080, ImageFormat.JPEG, 1);
                imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
                    @Override
                    public void onImageAvailable(ImageReader reader) {
                        Log.e(TAG, "onImageAvailable: "+"图片监听执行了" );
                        Image image = reader.acquireNextImage();
                        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                        byte[] data = new byte[buffer.remaining()];
                        buffer.get(data);
                        image.close();
                        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                        display.setImageBitmap(bitmap);
                        try {
                            galleryAddPhoto(MainActivity.this, bitmap);
                            DisplayMetrics metrics = new DisplayMetrics();
                            windowManager.getDefaultDisplay().getMetrics(metrics);
                            Bitmap snapShotImage = Bitmap.createBitmap(bitmap, metrics.widthPixels / 2 - 400, metrics.heightPixels / 2 - 400, 400, 400);
                            myBinder.floatView.setImageBitmap(snapShotImage);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }, null);
                cameraDevice.createCaptureSession(Arrays.asList(holder.getSurface(), recorderSurface,imageReader.getSurface()), new CameraCaptureSession.StateCallback() {
                    @Override
                    public void onConfigured(@NonNull CameraCaptureSession session) {
                        recorderSession = session;
                        try {
                            recorderSession.setRepeatingRequest(recorderRequestBuilder.build(), null, null);
                        } catch (CameraAccessException e) {
                            e.printStackTrace();
                        }
                        mediaRecorder.start();
                    }

                    @Override
                    public void onConfigureFailed(@NonNull CameraCaptureSession session) {

                    }
                }, null);
            } catch (CameraAccessException e) {
                e.printStackTrace();

        }
    }
    /**
     * 停止录像后，重新开启预览session
     */
    public void startPreViewSession(){
        try {
            cameraDevice.createCaptureSession(Arrays.asList(holder.getSurface(),imageReader.getSurface()), new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession session) {
                    previewSession = session;
                    startPreView();//必须放在这个回调方法里
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession session) {

                }
            }, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
    /**
     * 准备阶段mediaRecorder设置的参数信息
     */
    public void prepareRecorder(){
        mediaRecorder = new MediaRecorder();
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setOutputFile(getVideoFilePath());
        mediaRecorder.setVideoEncodingBitRate(10000000);
        if (slowMotionFlag) {
            mediaRecorder.setCaptureRate(120);
        }
        mediaRecorder.setVideoFrameRate(30);
//        mediaRecorder.setMaxDuration(3000);//设置最大录像时间
        Size videoSize = chooseVideoSize();
        mediaRecorder.setVideoSize(videoSize.getWidth(), videoSize.getHeight());
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        int orientation = 90;
        if (cameraId == CameraCharacteristics.LENS_FACING_BACK){
            orientation = 270;
            Log.e(TAG, "旋转了"+orientation );
        }
        mediaRecorder.setOrientationHint(orientation);
        mediaRecorder.setPreviewDisplay(holder.getSurface());
        //参数设置完毕后，调用prepare函数
        try {
            mediaRecorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取视频存储的路径
     * @return
     */
    private String getVideoFilePath() {
        File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
        String fileName = System.currentTimeMillis()+".mp4";
        videoFile = new File(file,fileName);
        return videoFile.getPath();
    }

    /**
     * //选择video存储的size
     * @return
     */
    private  Size chooseVideoSize() {
        Size[] sizes = map.getOutputSizes(MediaRecorder.class);
        for (Size size : sizes) {
            if (size.getWidth() == size.getHeight() * 4 / 3 && size.getWidth() <= 1080) {
                return size;
            }
        }
        return sizes[sizes.length - 1];
    }

    /**
     * //通知系统图库刷新图片，还有两种分别时mediastore和广播，其中广播和mediascannerconnection必须存储在外部共有目录。mediastore可以存储在外部私有目录，效率较低，会同时存储在公有目录和私有目录各一张
     * @param context
     * @param bitmap
     * @throws IOException
     */
    @SuppressLint("SimpleDateFormat")
    public void galleryAddPhoto(Context context,Bitmap bitmap) throws IOException {
        //存储图片到外部公有目录
        File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
        File file1 = new File(file, "camera2");
        if (!file1.exists()) file1.mkdirs();
        Log.e(TAG, "galleryAddPhoto: "+getLocation() );
        String fileName = getLocationAddress(getLocation())+System.currentTimeMillis()+".jpg";
        Log.e(TAG, "galleryAddPhoto: "+fileName );
//         String fileName = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(new Date())+".jpg";
//        File imageFile = File.createTempFile(fileName, ".jpeg", file1);
        File imageFile = new File(file1, fileName);
        FileOutputStream fos = new FileOutputStream(imageFile);
        bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
        fos.flush();
        fos.close();
        MediaScannerConnection.scanFile(context,new String[]{imageFile.getAbsolutePath()},new String[]{"image/jpeg"},null);
        getPhotoAddress(imageFile.getAbsolutePath());
    }
    /**
     * 通知图库刷新video视频
     * @param context
     */
    public void galleryAddVideo(Context context){
        MediaScannerConnection.scanFile(context,new String[]{videoFile.getAbsolutePath()},new String[]{"video/mp4"},null);
    }
    public void stopVideo(){
        if (mediaRecorder!=null){
            mediaRecorder.stop();
            mediaRecorder.release();
        }
    }
    private Location getLocation(){
        if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED&&
         checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED&&
        checkSelfPermission(Manifest.permission.INTERNET)==PackageManager.PERMISSION_GRANTED){
//            // 生成一个Criteria对象
//            Criteria criteria = new Criteria();
//            // 设置查询条件
//            criteria.setAccuracy(Criteria.ACCURACY_FINE); // 设置准确而非粗糙的精度
//            criteria.setPowerRequirement(Criteria.POWER_LOW); // 设置相对省电而非耗电，一般高耗电量会换来更精确的位置信息
//            criteria.setAltitudeRequired(false); // 不需要提供海拔信息
//            criteria.setSpeedRequired(false); // 不需要速度信息
//            criteria.setCostAllowed(false); // 不能产生费用
            // 第一个参数，传递criteria对象
            // 第二个参数，若为false,在所有Provider中寻找，不管该Provider是否处于可用状态，均使用该Provider。
            // 若为true，则在所有可用的Provider中寻找。比如GPS处于禁用状态，则忽略GPS Provider。
            // 1、可用中最好的
//            String locationProvider = locationManager.getBestProvider(criteria, true);
            String locationProvider = "";
            // 2、所有可用的中的第一个
                //获取位置信息提供者列表
                List<String> providerList = locationManager.getProviders(true);

                if (providerList.contains(LocationManager.NETWORK_PROVIDER)){
                    //获取NETWORK定位
                    locationProvider = LocationManager.NETWORK_PROVIDER;
                }else if (providerList.contains(LocationManager.GPS_PROVIDER)){
                    //获取GPS定位
                    locationProvider = LocationManager.GPS_PROVIDER;
                }

            Log.e(TAG, "getLocation: "+locationProvider );
            Location location = locationManager.getLastKnownLocation(locationProvider);
            return location;
        }
        return null;
    }

    /**
     * 照片中写入经纬度扩展信息
     * @param path
     * @throws IOException
     */
    private void getPhotoAddress(String path) throws IOException {
        ExifInterface exif = new ExifInterface(path);
        Location location = getLocation();
        //纬度
       exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, String.valueOf(location.getLatitude()));
        //经度
       exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, String.valueOf(location.getLongitude()));
       exif.setAttribute(ExifInterface.TAG_DATETIME,String.valueOf(location.getTime()));
       exif.saveAttributes();
    }
    /**
     * 将经纬度转换成中文地址
     *
     * @param location
     * @return
     */
    private String getLocationAddress(Location location) {
        Log.e(TAG, "getLocationAddress: "+location );
        String add = "";
        Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.CHINESE);
        try {

            List<Address> addresses = geoCoder.getFromLocation(
                    location.getLatitude(), location.getLongitude(),
                    1);
            Address address = addresses.get(0);
            Log.i(TAG, "getLocationAddress: " + address.toString());
            int maxLine = address.getMaxAddressLineIndex();
            if (maxLine >= 2) {
                add = address.getAddressLine(1) + address.getAddressLine(2);
            } else {
                add = address.getAddressLine(0);
            }
        } catch (IOException e) {
            add = "";
            e.printStackTrace();
        }
        return add;
}

    @Override
    protected void onStop() {
        super.onStop();
        SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
        sharedPreferences.edit().putString("time", String.valueOf(this.time)).apply();
    }

}